package com.bistu.openlab.zipdeal;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/*
 *@author xiaoguang.gao@oracle.com
 *@version 2013-5-8 
 */
public class Zip {
	private ZipInputStream  zipIn;      //��ѹZip 
    private ZipOutputStream zipOut;     //ѹ��Zip 
    private ZipEntry        zipEntry; 
    private static int      bufSize;    //size of bytes 
    private byte[]          buf; 
    private int             readedBytes; 
     
    public Zip(){ 
        this(512); 
    } 

    public Zip(int bufSize){ 
        this.bufSize = bufSize; 
        this.buf = new byte[this.bufSize]; 
    } 
    private int srcDirLength = 0;
    //ѹ���ļ����ڵ��ļ� 
    public void doZip(String zipDirectory,String targetFile){//zipDirectoryPath:��Ҫѹ�����ļ����� 
        File file; 
        File zipDir; 
        
        zipDir = new File(zipDirectory); 
        this.srcDirLength = zipDir.getAbsolutePath().length();
        
        String zipFileName = targetFile;//ѹ������ɵ�zip�ļ��� 

        try{ 
            this.zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName))); 
            handleDir(zipDir , this.zipOut); 
            this.zipOut.close(); 
        }catch(Exception ioe){ 
            ioe.printStackTrace(); 
        } 
    } 

    //��doZip����,�ݹ����Ŀ¼�ļ���ȡ
    private void handleDir(File dir, ZipOutputStream zipOut)throws Exception{ 
        FileInputStream fileIn; 
        File[] files; 

        files = dir.listFiles(); 
        if(files.length == 0){//���Ŀ¼Ϊ��,�򵥶�����֮. 
            //ZipEntry��isDirectory()������,Ŀ¼��"/"��β. 
            this.zipOut.putNextEntry(new ZipEntry(dir.toString() + "/")); 
            this.zipOut.closeEntry(); 
        } 
        else{//���Ŀ¼��Ϊ��,��ֱ���Ŀ¼���ļ�. 
            for(File fileName : files){
            	if(fileName.isFile()){
            		fileIn = new FileInputStream(fileName);
                    String name=dir.getAbsolutePath()+File.separator;//.getName();
                    name = name.substring(this.srcDirLength);
                    if(name.startsWith(File.separator)){
                    	name = name.substring(1);
                    }
                    this.zipOut.putNextEntry(new ZipEntry(name+fileName.getName().toString())); 
                    //�˷�������ڸ���ĿĿ¼��
                    //this.zipOut.putNextEntry(new ZipEntry(fileName.toString()));
                    while((this.readedBytes=fileIn.read(this.buf))>0){
                        this.zipOut.write(this.buf , 0 , this.readedBytes);
                    }
                    this.zipOut.closeEntry(); 
            	}else{
            		handleDir(fileName , this.zipOut);
            	}
            } 
        } 
    } 

    //��ѹָ��zip�ļ� 
    public void unZip(String unZipfileName,String targetDic){//unZipfileName��Ҫ��ѹ��zip�ļ��� 
        FileOutputStream fileOut; 
        File file; 
        String f=targetDic;//unZipfileName.substring(0, unZipfileName.length()-4);
        File ff=new File(f);
        try{ 
            this.zipIn = new ZipInputStream (new 
            		BufferedInputStream(new FileInputStream(unZipfileName))); 
            while((this.zipEntry = this.zipIn.getNextEntry()) != null){ 
                file = new File(this.zipEntry.getName()); 
                if(this.zipEntry.isDirectory()){ 
                    file.mkdirs(); 
                } 
                else{ 
                    File parent = file.getParentFile();
                    if(parent!=null)
	                    if(!parent.exists()){ 
	                        parent.mkdirs(); 
	                    } 
                    if(!ff.exists()){
                    	ff.mkdirs();
                    }
                    File fi = new File(".");
                    String currentDir = fi.getAbsolutePath();
                    currentDir = currentDir.substring(0, currentDir.length()-1);
                    String currentFile = f+File.separator+file.getAbsolutePath().substring(currentDir.length());
                    if(currentFile.lastIndexOf(file.separator)>=0){
                    	currentDir = currentFile.substring(0,currentFile.lastIndexOf(File.separator));
                    	File dir = new File(currentDir);
                    	if(!dir.exists()){
                    		dir.mkdirs();
                    	}
                    }
                    fileOut = new FileOutputStream(currentFile); 
                    
                    //fileOut = new FileOutputStream(file); �˷�����ŵ�����ĿĿ¼��
                    while(( this.readedBytes = this.zipIn.read(this.buf) ) > 0){ 
                        fileOut.write(this.buf , 0 , this.readedBytes ); 
                    } 
                    fileOut.close(); 
                }
                
                this.zipIn.closeEntry();
            }
        }catch(Exception ioe){
            ioe.printStackTrace(); 
        }
    } 

    //���û������С 
    public void setBufSize(int bufSize){ 
        this.bufSize = bufSize; 
    } 

    //����Zip�� 
    public static void main(String[] args)throws Exception{ 
        Zip zip=new Zip();
        zip.doZip("D:\\convert","D:\\xiao.zip");
        //zip.unZip("D:\\xiao.zip","D:\\gal");
        
    } 
}
